package com.fsserver.core.service.impl;

import com.fsserver.common.api.ResultCode;
import com.fsserver.common.exception.BusinessException;
import com.fsserver.core.dto.PaymentRequestDTO;
import com.fsserver.core.dto.RefundRequestDTO;
import com.fsserver.core.service.AlipayService;
import com.fsserver.core.service.PaymentGatewayService;
import com.fsserver.core.service.WechatPayService;
import com.fsserver.core.vo.PaymentResponseVO;
import com.fsserver.core.vo.RequestNotification;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 统一支付网关服务实现类
 * Unified Payment Gateway Service Implementation
 *
 * @author fsserver
 */
@Slf4j
@Service
public class PaymentGatewayServiceImpl implements PaymentGatewayService {

    @Autowired
    private WechatPayService wechatPayService;

    @Autowired
    private AlipayService alipayService;

    /**
     * 支付渠道：微信支付
     */
    private static final String CHANNEL_WECHAT = "WECHAT";

    /**
     * 支付渠道：支付宝支付
     */
    private static final String CHANNEL_ALIPAY = "ALIPAY";

    @Override
    public PaymentResponseVO createPayment(PaymentRequestDTO requestDTO) {
        validateNotNull(requestDTO, "支付请求不能为空");
        
        String paymentChannel = requestDTO.getPaymentChannel();
        validateNotEmpty(paymentChannel, "支付渠道不能为空");

        // 根据支付渠道选择相应的支付服务
        if (CHANNEL_WECHAT.equals(paymentChannel)) {
            log.info("使用微信支付渠道，订单号：{}, 支付类型: {}", requestDTO.getOrderNo(), requestDTO.getPaymentType());
            return wechatPayService.createPayment(requestDTO);
        } else if (CHANNEL_ALIPAY.equals(paymentChannel)) {
            log.info("使用支付宝支付渠道，订单号：{}, 支付类型: {}", requestDTO.getOrderNo(), requestDTO.getPaymentType());
            return alipayService.createPayment(requestDTO);
        } else {
            log.error("不支持的支付渠道：{}", paymentChannel);
            throw new BusinessException(ResultCode.PARAM_ERROR, "不支持的支付渠道：" + paymentChannel);
        }
    }

    @Override
    public Map<String, Object> queryOrder(String orderNo, String paymentChannel) {
        validateNotEmpty(orderNo, "订单号不能为空");
        validateNotEmpty(paymentChannel, "支付渠道不能为空");

        // 根据支付渠道选择相应的支付服务
        if (CHANNEL_WECHAT.equals(paymentChannel)) {
            log.info("查询微信支付订单，订单号：{}", orderNo);
            return wechatPayService.queryOrder(orderNo);
        } else if (CHANNEL_ALIPAY.equals(paymentChannel)) {
            log.info("查询支付宝支付订单，订单号：{}", orderNo);
            return alipayService.queryOrder(orderNo);
        } else {
            log.error("不支持的支付渠道：{}", paymentChannel);
            throw new BusinessException(ResultCode.PARAM_ERROR, "不支持的支付渠道：" + paymentChannel);
        }
    }

    @Override
    public boolean closeOrder(String orderNo, String paymentChannel) {
        validateNotEmpty(orderNo, "订单号不能为空");
        validateNotEmpty(paymentChannel, "支付渠道不能为空");

        // 根据支付渠道选择相应的支付服务
        if (CHANNEL_WECHAT.equals(paymentChannel)) {
            log.info("关闭微信支付订单，订单号：{}", orderNo);
            return wechatPayService.closeOrder(orderNo);
        } else if (CHANNEL_ALIPAY.equals(paymentChannel)) {
            log.info("关闭支付宝支付订单，订单号：{}", orderNo);
            return alipayService.closeOrder(orderNo);
        } else {
            log.error("不支持的支付渠道：{}", paymentChannel);
            throw new BusinessException(ResultCode.PARAM_ERROR, "不支持的支付渠道：" + paymentChannel);
        }
    }

    @Override
    public Map<String, Object> refund(String orderNo, String refundNo, Long totalAmount, Long refundAmount, String reason, String paymentChannel) {
        validateNotEmpty(orderNo, "订单号不能为空");
        validateNotEmpty(refundNo, "退款单号不能为空");
        validatePositive(totalAmount, "订单总金额必须大于0");
        validatePositive(refundAmount, "退款金额必须大于0");
        validateNotEmpty(paymentChannel, "支付渠道不能为空");

        // 根据支付渠道选择相应的支付服务
        if (CHANNEL_WECHAT.equals(paymentChannel)) {
            log.info("申请微信支付退款，订单号：{}，退款单号：{}", orderNo, refundNo);
            return wechatPayService.refund(orderNo, refundNo, totalAmount, refundAmount, reason);
        } else if (CHANNEL_ALIPAY.equals(paymentChannel)) {
            log.info("申请支付宝支付退款，订单号：{}，退款单号：{}", orderNo, refundNo);
            return alipayService.refund(orderNo, refundNo, totalAmount, refundAmount, reason);
        } else {
            log.error("不支持的支付渠道：{}", paymentChannel);
            throw new BusinessException(ResultCode.PARAM_ERROR, "不支持的支付渠道：" + paymentChannel);
        }
    }
    
    @Override
    public Map<String, Object> refund(RefundRequestDTO refundRequestDTO, String paymentChannel) {
        validateNotNull(refundRequestDTO, "退款请求对象不能为空");
        validateNotEmpty(paymentChannel, "支付渠道不能为空");
        
        // 从RefundRequestDTO中提取参数
        String orderNo = refundRequestDTO.getOrderNo();
        String refundNo = refundRequestDTO.getRefundNo();
        BigDecimal refundAmount = refundRequestDTO.getAmount();
        BigDecimal totalAmount = refundRequestDTO.getTotalAmount();
        String reason = refundRequestDTO.getReason();

        // 参数校验
        validateNotEmpty(orderNo, "订单号不能为空");
        validateNotEmpty(refundNo, "退款单号不能为空");
        validateNotNull(refundAmount, "退款金额不能为空");
        validateNotNull(totalAmount, "订单总金额不能为空");
        
        if (refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "退款金额必须大于0");
        }
        
        if (totalAmount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "订单总金额必须大于0");
        }

        // 金额单位转换为分
        Long refundAmountInCents = refundAmount.multiply(new BigDecimal("100")).longValue();
        Long totalAmountInCents = totalAmount.multiply(new BigDecimal("100")).longValue();

        return refund(orderNo, refundNo, totalAmountInCents, refundAmountInCents, reason, paymentChannel);
    }

    @Override
    public Map<String, Object> queryRefund(String refundNo, String paymentChannel) {
        validateNotEmpty(refundNo, "退款单号不能为空");
        validateNotEmpty(paymentChannel, "支付渠道不能为空");

        // 根据支付渠道选择相应的支付服务
        if (CHANNEL_WECHAT.equals(paymentChannel)) {
            log.info("查询微信支付退款，退款单号：{}", refundNo);
            return wechatPayService.queryRefund(refundNo);
        } else if (CHANNEL_ALIPAY.equals(paymentChannel)) {
            log.info("查询支付宝支付退款，退款单号：{}", refundNo);
            return alipayService.queryRefund(refundNo);
        } else {
            log.error("不支持的支付渠道：{}", paymentChannel);
            throw new BusinessException(ResultCode.PARAM_ERROR, "不支持的支付渠道：" + paymentChannel);
        }
    }

    @Override
    public boolean handlePaymentNotification(RequestNotification notification) {
        validateNotNull(notification, "支付通知对象不能为空");

        String paymentChannel = notification.getPaymentType();
        validateNotEmpty(paymentChannel, "支付通知中支付渠道不能为空");

        // 根据支付渠道选择相应的支付服务
        if (CHANNEL_WECHAT.equals(paymentChannel)) {
            log.info("处理微信支付通知，请求ID：{}", notification.getRequestId());
            return wechatPayService.handlePaymentNotification(notification);
        } else if (CHANNEL_ALIPAY.equals(paymentChannel)) {
            log.info("处理支付宝支付通知，请求ID：{}", notification.getRequestId());
            return alipayService.handlePaymentNotification(notification);
        } else {
            log.error("不支持的支付渠道：{}", paymentChannel);
            return false;
        }
    }

    @Override
    public boolean handleRefundNotification(RequestNotification notification) {
        validateNotNull(notification, "退款通知对象不能为空");

        String paymentChannel = notification.getPaymentType();
        validateNotEmpty(paymentChannel, "退款通知中支付渠道不能为空");

        // 根据支付渠道选择相应的支付服务
        if (CHANNEL_WECHAT.equals(paymentChannel)) {
            log.info("处理微信支付退款通知，请求ID：{}", notification.getRequestId());
            return wechatPayService.handleRefundNotification(notification);
        } else if (CHANNEL_ALIPAY.equals(paymentChannel)) {
            log.info("处理支付宝支付退款通知，请求ID：{}", notification.getRequestId());
            return alipayService.handleRefundNotification(notification);
        } else {
            log.error("不支持的支付渠道：{}", paymentChannel);
            return false;
        }
    }
    
    /**
     * 验证对象非空
     */
    private void validateNotNull(Object obj, String message) {
        if (obj == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, message);
        }
    }
    
    /**
     * 验证字符串非空
     */
    private void validateNotEmpty(String str, String message) {
        if (StringUtils.isEmpty(str)) {
            throw new BusinessException(ResultCode.PARAM_ERROR, message);
        }
    }
    
    /**
     * 验证数值为正数
     */
    private void validatePositive(Long value, String message) {
        if (value == null || value <= 0) {
            throw new BusinessException(ResultCode.PARAM_ERROR, message);
        }
    }
} 